
package analiseSintatica.Regras.Expressoes;

import java.util.LinkedList;

import analiseSintatica.AnalisadorSintatico;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;

import analiseSemantica.ErroSemantico;
import analiseSemantica.Tipos.TipoSemantico;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSemantica.estruturadedados.Identificador;
import analiseSemantica.estruturadedados.Token;

/**
 * Contem as regras para Unario Posfixa
 * @author Nathalia
 * nathy
 */
public class RegraUnarioPosfixa extends Regra {

    protected static Regra instancia;

    protected static String estrutura = "<elemento> |  identificador";
    /**
     * Construtor privado necessario ao singleton
     */
    private RegraUnarioPosfixa() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraUnarioPosfixa getInstance() {
        if (instancia == null) {
            instancia = new RegraUnarioPosfixa();
        }
        return (RegraUnarioPosfixa) instancia;
    }

    /**
     * Realiza analise sintatica
     * @param listaTokens - Tokens do codigo
     * @return - Arvore sintatica
     * @throws Exception
     */	
	@Override
	public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException{


        TiposSemanticos tiposemanticos = new TiposSemanticos();

        if (listaContem(RegraElemento.getInstance().getPrimeiro(), listaTokens.getFirst())) {   
        	return RegraElemento.getInstance().analisar(listaTokens);
        }else if(listaTokens.getFirst().getToken().equals("identificador")){
            
            LinkToken token = listaTokens.getFirst();
            reconheceToken(listaTokens, "identificador", estrutura);
            
            Token id = AnalisadorSintatico.escopoatual.find(token.getLexema());
            if(id == null || !(id instanceof Identificador)){
            	AnalisadorSintatico.errosemanticos.add(new ErroSemantico("Identificador "+token.getLexema()+" nao encontrado",token.getLinha()));
    			tiposemanticos = null;
    		}else{
    			Identificador id2 = (Identificador)id;
    			tiposemanticos.addTipos(new TipoSemantico(id2.getTipo(), token.getLinha()));
    		}
           
        }else{
            ErroSintaticoException e = new ErroSintaticoException();
            e.addErros("Unario Pos-Fixa esperada antes do token " + listaTokens.getFirst().getLexema(), estrutura, listaTokens.getFirst().getLinha());
            throw e;
        }
           
        return tiposemanticos;
	}
	

  
    @Override
    protected void setPrimeiro() {
       this.primeiro = RegraElemento.getInstance().getPrimeiro();
       this.primeiro = getUniao(primeiro, "identificador");
    }


}
